<?php

namespace App\Kuafu\Order\Jobs;

use App\Kuafu\Activity\Enum\ActivityEnum;
use App\Kuafu\Activity\Model\ActivityProductMappingModel;
use App\Kuafu\Activity\Service\ActivityService;
use App\Kuafu\Common\Jobs\SensorsDataJob;
use App\Kuafu\Common\Service\CommonService;
use App\Kuafu\CustomerCoupon\Model\CustomerSendCouponLogModel;
use App\Kuafu\Order\Enum\CodeEnum;
use App\Kuafu\Order\Model\OrderCouponSplitModel;
use App\Kuafu\Order\Model\OrderDetailSplitModel;
use App\Kuafu\Order\Model\OrderExternalSplitModel;
use App\Kuafu\Order\Model\OrderSplitModel;
use App\Kuafu\Product\Service\ProductService;
use App\Kuafu\Shop\Model\Shop;
use App\Kuafu\Shop\Service\ShopService;
use App\Library\SnowFlake\SnowFlake;
use Exception;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\DB;


/**
 * @description 支付回调消息队列
 *
 * @queueName {PAY_ORDER_NOTIFY_QUEUE}
 */
class PayNotifyJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    /**
     * 异常标题
     */
    const EXCEPTION_TITLE = '【 消费队列 】【 支付回调 】';

    /**
     * 队列名称
     *
     * @var string
     */
    public static string $QUEUE_NAME = '{RMS-PAY-ORDER-NOTIFY-QUEUE}';

    /**
     * 门店id
     *
     * @var int
     */
    public int $shopId;


    /**
     * 订单id
     *
     * @var int
     */
    public $orderId;

    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct($shopId, $orderId)
    {
        $this->orderId = $orderId;
        $this->shopId  = $shopId;
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        try {
            //订单信息
            $orderObject = OrderSplitModel::suffix($this->shopId)
                                          ->query()
                                          ->where('orderId', (int)$this->orderId)
                                          ->first();
            if (empty($orderObject)) {
                throw new Exception('订单查询失败');
            }

            //获取菜品详情数据
            $orderDetailObject = OrderDetailSplitModel::suffix($this->shopId)
                                                      ->query()
                                                      ->where('orderId', (int)$this->orderId)
                                                      ->get();
//
//            //获取订单优惠券使用
//            $orderCouponObject = OrderCouponSplitModel::suffix($this->shopId)
//                                                      ->query()
//                                                      ->where('orderId', (int)$this->orderId)
//                                                      ->get();


            // 新增常去门店处理
            ShopService::shopUserUsuallyAdd($orderObject->userId, $this->shopId);

            /*     //小程序下单 丢入神策埋点
                 if ($orderObject->sourceType == CodeEnum::SOURCE_TYPE_MINI) {
                     $this->sensorsDataHandle($orderObject, $orderDetailObject, $orderCouponObject);
                 }*/


            // todo  处理满赠活动
            $this->handleGiftActivity($orderObject, $orderDetailObject);
        } catch (Exception $e) {
            CommonService::fsLogException(self::EXCEPTION_TITLE, $e,
                Collect(get_object_vars($this))->only(['shopId', 'orderId', 'queue'])->toArray(), true);
        }

    }


    /**
     * 神策埋点处理
     *
     * @param Model|object|static|null $orderObject
     * @param Collection|static[] $orderDetailObject
     * @param Collection|static[] $orderCouponObject
     */
    public function sensorsDataHandle($orderObject, $orderDetailObject, $orderCouponObject)
    {
        /*  //丢入神策埋点【 支付成功 】
          SensorsDataJob::dispatch(
              $this->shopId,
              $orderObject->userId,
              SensorsDataJob::TYPE_PAY_SUCCESS,
              [
                  'pay_type'        => (string)'微信支付',//支付方式 |STRING|
                  'order_time'      => date('Y-m-d H:i:s', $orderObject->createdAt->timestamp),//订单时间 |DATETIME|
                  'order_no'        => (string)$orderObject->orderId,//订单编号 |STRING|
                  'order_amount'    => bcdiv($orderObject->originalPrice, 100,2),//订单金额 |NUMBER| 菜品总金额：统计所有菜品⾦额=
                  'discount_amount' => (string)bcdiv($orderObject->discountPrice, 100, 2),//优惠折扣 |STRING|
                  'pay_amount'      => bcdiv($orderObject->payPrice, 100, 2),//优惠后金额 |NUMBER| 优惠后的菜品总金额
                  'if_consumCoupon' => (bool)$orderCouponObject->isNotEmpty(),//是否使用优惠券 |BOOL|
                  'coupon_quantity' => $orderCouponObject->count(),//优惠券数量 |number|
                  'menu_number'     => (string)$orderObject->serialNum,//取餐号 |STRING|
                  'comment'         => (string)$orderObject->remark,//备注 |STRING| 口味，偏好备注内容
              ]
          )->onQueue(SensorsDataJob::$QUEUE_NAME);


          //丢入神策埋点【 支付成功 】【 菜品详情 】
          $orderDetailObject->each(function ($item) use ($orderObject) {
              SensorsDataJob::dispatch(
                  $this->shopId,
                  $orderObject->userId,
                  SensorsDataJob::TYPE_PAY_SUCCESS_MENU_DETAIL,
                  [
                      'order_time'         => date('Y-m-d H:i:s', $orderObject->createdAt->timestamp),//订单时间 |DATETIME|
                      'order_no'           => (string)$item->orderId,//订单编号 |STRING|
                      'menu_type'          => (string)\App\Kuafu\Product\Enum\CodeEnum::TYPE_PRODUCT_TYPE_TEXT[$item->type] ?? '单品', //菜品分类 |STRING| 必吃，素串系列，卤油炸串，套餐类等
                      'menu_name'          => (string)$item->productName,//菜品名称 |STRING| 如果是套餐组合，传套餐名称
                      'menu_originalPrice' => (string)bcdiv($item->originalUnitPrice, 100, 2),//菜品原价 |STRING|
                      'menu_quantity'      => (string)$item->num,//菜品数量 |STRING|
                      'menu_amount'        => bcdiv($item->originalPrice, 100, 2),//菜品金额 |NUMBER| 菜品⾦额默认为菜品原价*菜品份额
                      'discount_amount'    => (string)bcdiv($item->totalDiscountPrice, 100 ,2),//优惠折扣 |STRING|
                      'pay_amount'         => bcdiv($item->payPrice, 100, 2),//优惠后金额 |NUMBER| 优惠后的菜品总金额
                      'menu_number'        => (string)$orderObject->serialNum,//取餐号 |STRING|
                      'comment'            => (string)$orderObject->remark,//备注 |STRING| 口味，偏好备注内容
                  ]
              )->onQueue(SensorsDataJob::$QUEUE_NAME);
          });*/
    }

    /**
     * 同步 满赠活动库存 & 参与记录
     *
     * @param OrderSplitModel $orderObject
     * @param \Illuminate\Support\Collection $orderDetailObject
     * @throws Exception
     */
    public function handleGiftActivity(OrderSplitModel $orderObject, \Illuminate\Support\Collection $orderDetailObject)
    {
        try {
            $exists = OrderExternalSplitModel::suffix($this->shopId)->where([
                "shopId"  => $this->shopId,
                "type"    => CodeEnum::ORDER_EXTERNAL_TYPE_ACTIVITY,
                "orderId" => (int)$this->orderId
            ])->first();

            if($exists){
                return;
            }

            $channel = null;
            switch ($orderObject->sourceType) {
                case $orderObject->sourceType == CodeEnum::SOURCE_TYPE_MINI:
                    $channel = ActivityEnum::CHANNEL_APPLET;
                    break;
                case $orderObject->sourceType == CodeEnum::SOURCE_TYPE_POS:
                    $channel = ActivityEnum::CHANNEL_POS;
                    break;
            }

            if ($channel) {
                // 仅限 小程序 & pos渠道订单
                $shopGiftActivity = ActivityService::getShopGiftActivityDetail(
                    Shop::query()->where("id", $this->shopId)->first(),
                    $channel
                );

                if ($shopGiftActivity) {
                    $giftProductsCollection = collect($shopGiftActivity["giftProductIds"]);

                    // ToDo 判断是否参与当前活动
                    $exists = $orderDetailObject->whereIn(
                        "productId", $giftProductsCollection->pluck("productId")->toArray()
                    )->count();

                    if ($exists) {
                        // todo  库存限制赠品 更新库存
                        $giftProductsCollection
                            ->where("giveStockRuleType", ActivityProductMappingModel::GIVE_STOCK_RULE_TYPE_1)
                            ->each(function (array $giftProduct) use ($orderDetailObject) {
                                $giftProductSum = $orderDetailObject
                                    ->where("productId", $giftProduct["productId"])
                                    ->pluck("num")
                                    ->sum();
                                if ($giftProductSum > 0) {
                                    // todo 更新活动赠品库存
                                    ActivityProductMappingModel::query()->where("id", $giftProduct["id"])->update([
                                        "stockNum" => DB::raw("stockNum - {$giftProductSum}")
                                    ]);

                                    $stockNum = ActivityProductMappingModel::query()->where("id", $giftProduct["id"])->first()->stockNum;
                                    if ($stockNum <= 0) {
                                        // todo 操作估清
                                        ProductService::posStatus($this->shopId, 1, (object)[
                                            "out"    => 1,
                                            "status" => 0,
                                            "id"     => $giftProduct["productId"]
                                        ]);
                                    }
                                }
                            });

                        // todo 三方订单表 - 活动参与记录写入
                        OrderExternalSplitModel::suffix($this->shopId)->insert([
                            "id"         => SnowFlake::nextIdCache(),
                            "brandId"    => 1,
                            "shopId"     => $this->shopId,
                            "type"       => CodeEnum::ORDER_EXTERNAL_TYPE_ACTIVITY,
                            "orderId"    => $this->orderId,
                            "extOrderId" => $shopGiftActivity["id"],
                            "createdAt"  => time()
                        ]);

                        //todo 更新活动参与记录
                        CustomerSendCouponLogModel::query()->insert([
                            "userId"       => $orderObject->userId,
                            "shopId"       => $this->shopId,
                            "activityId"   => $shopGiftActivity["id"],
                            "activityType" => $shopGiftActivity["type"],
                            "createdAt"    => time()
                        ]);
                    }
                }
            }
        } catch (Exception $exception) {
            logException("订单支付成功处理满赠活动异常", $exception, ["shopId" => $this->shopId, "orderId" => $this->orderId]);
        }
    }
}
